package com.jd.platform.gobrs.client.handler.manual;

import com.jd.platform.gobrs.client.callback.ValueModel;
import com.jd.platform.gobrs.client.core.key.IKeyOwner;
import com.jd.platform.gobrs.client.core.key.manual.ManualKeyBuilder;
import com.jd.platform.gobrs.client.core.key.KeyHandlerFactory;
import com.jd.platform.gobrs.client.core.key.KeyHotModel;
import com.jd.platform.gobrs.client.handler.AbstractManualCacheHandler;
import com.jd.platform.gobrs.common.model.typeenum.KeyType;
import com.jd.platform.gobrs.common.tool.Constant;

/**
 * @program: gobrs
 * @ClassName ManualCache
 * @description:
 * @author: sizegang
 * @create: 2022-01-08 15:26
 * @Version 1.0
 **/
public class ManualCache<T> extends AbstractManualCacheHandler {


    private ManualKeyBuilder manualKeyBuilder = IKeyOwner.getManualKeyBuilder();

    @Override
    public Object doGetCache(String key) {
        return doGetCache(key, null);
    }

    @Override
    public Object doGetCache(String key, KeyType keyType) {
        try {
            //如果没有为该key配置规则，就不用上报key
            if (!inRule(key)) {
                return null;
            }
            Object userValue = null;
            ValueModel value = getValueSimple(key);
            if (value == null) {
                // 配置了规则 但是本地没有缓存 可能情况 访问并发还不够规则的触发值，如果触发规则限流操作  worker会下发通知 client 进行本地缓存
                manualKeyBuilder.buildPrepareSend(key, keyType);
            } else {
                //临近过期了，也发
                if (isNearExpire(value)) {
                    manualKeyBuilder.buildPrepareSend(key, keyType);
                }
                Object object = value.getValue();
                //如果是默认值，也返回null
                if (object instanceof Integer && Constant.MAGIC_NUMBER == (int) object) {
                    userValue = null;
                } else {
                    userValue = object;
                }
            }

            //统计计数
            KeyHandlerFactory.getCounter().collect(new KeyHotModel(key, value != null));

            return userValue;
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public Integer getType() {
        return getType();
    }

    @Override
    public boolean isHotKey(String key) {
        return isHot(key);
    }

    @Override
    public void remove(String key) {
        remove(key);
    }

//    @Override
//    public boolean doSetCache(String key, Object value) {
//        if (isHot(key)) {
//            ValueModel valueModel = getValueSimple(key);
//            if (valueModel == null) {
//                return false;
//            }
//            valueModel.setValue(value);
//            return true;
//        }
//        return false;
//    }
//
//
//    /**
//     * 判断是否配置了规则 key， 如果是配置了，则发往worker
//     */
//    @Override
//    public boolean isHotKey(String key) {
//        try {
//            // 如果没有配置规则 则不发往server
//            if (!inRule(key)) {
//                return false;
//            }
//            boolean isHot = isHot(key);
//            if (!isHot) {
//                manualKeyBuilder.buildPrepareSend(key, null);
//            } else {
//                ValueModel valueModel = getValueSimple(key);
//                //判断是否过期时间小于1秒，小于1秒的话也发送
//                if (isNearExpire(valueModel)) {
//                    manualKeyBuilder.buildPrepareSend(key, null);
//                }
//            }
//
//            //统计计数
//            KeyHandlerFactory.getCounter().collect(new KeyHotModel(key, isHot));
//            return isHot;
//        } catch (Exception e) {
//            return false;
//        }
//
//    }
//
//    /**
//     * 直接取 不涉及推送
//     * 从本地caffeine取值
//     */
//    public Object get(String key) {
//        ValueModel value = getValueSimple(key);
//        if (value == null) {
//            return null;
//        }
//        Object object = value.getValue();
//        //如果是默认值也返回null
//        if (object instanceof Integer && Constant.MAGIC_NUMBER == (int) object) {
//            return null;
//        }
//        return object;
//    }
//
//    /**
//     * 强制给value赋值
//     */
//    public void forceSet(String key, Object value) {
//        ValueModel valueModel = ValueModel.defaultValue(key);
//        if (valueModel != null) {
//            valueModel.setValue(value);
//        }
//        setValueDirectly(key, valueModel);
//    }
//
//
//    /**
//     * 纯粹的本地缓存，无需该key是热key
//     * add newKey 设置默认 ValueModel 占位
//     */

//
//    /**
//     * 删除某key，会通知整个集群删除
//     */
//    public void remove(String key) {
//        getNonNullCache(key).delete(key);
//        manualKeyBuilder.remove(key);
//    }
//
//
//    /**
//     * 判断这个key是否在被探测的规则范围内
//     */
//    private boolean inRule(String key) {
//        return manualLocalCacheFactory.getNonNullCache(key) != null;
//    }
//
//
//    private LocalCache getNonNullCache(String key) {
//        return manualLocalCacheFactory.getNonNullCache(key);
//    }
//
//    /**
//     * 此方法有三种情况
//     * 1. 如果没有配置规则则返回null
//     * 2. 如果配置了规则，当前key没有热， 则返回null
//     * 3. 配置了规则 也热key了 则返回值
//     */
//    public ValueModel getValueSimple(String key) {
//        Object object = getNonNullCache(key).get(key);
//        if (object == null) {
//            return null;
//        }
//        return (ValueModel) object;
//    }
//
//
//    @Override
//    public Integer getType() {
//        return CacheHandlerEnums.MANUAL_CACHE.getType();
//    }
//
//    /**
//     * 从本地cafine中获取 如果存在则说明已经被缓存成热点key
//     * 判断是否是热key。适用于只需要判断key，而不需要value的场景
//     */
//    public boolean isHot(String key) {
//        return getValueSimple(key) != null;
//    }
}
